// TPDialogX.h
//
// TPDialogX desktop and mobile sample classes


#pragma once
#include "atldlgx.h"
#include "filecontrols.h"
#include <atlmisc.h>

////////////////////////////////////////////////////////////
// CTPToolMenu

#ifdef _WIN32_WCE
typedef CCellMenu<IDR_MAINFRAME, 6, 1> CTPToolMenu;
#ifdef _WTL_CE_DRA // resolution awareness

const SIZE CTPToolMenu::CellSize()
{
	SIZE size;
	CBitmap bm = AtlLoadBitmap(IDR_MAINFRAME);
	ATLASSERT(!bm.IsNull());

	SIZE sbm;
	bm.GetSize(sbm);
	size.cx = DRA::SCALEX(sbm.cx / (t_nCol * t_nRow)) + 2 * CELL::Cxy();
	size.cy = DRA::SCALEY(sbm.cy) + 2 * CELL::Cxy();

	return size;
}

CImageList& CTPToolMenu::GetImageList()
{
	static CImageList iml;
	if (iml.IsNull())
	{
		iml = DRA::ImageList_LoadImage(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(IDR_MAINFRAME),
									   DRA::UNSCALEX(CELL::Size().cx - 2 * CELL::Cxy()), 0, CLR_DEFAULT, IMAGE_BITMAP, 0);
	}

	ATLASSERT(!iml.IsNull());

	return iml;
}
#endif // _WTL_CE_DRA
#endif // _WIN32_WCE

////////////////////////////////////////////////////////////
// CTPColorMenu

#ifndef ID_COLORMENU
#define ID_COLORMENU 1001
#endif

typedef CCellMenu<ID_COLORMENU, 8, 5> CTPColorMenu;

// Color table
__declspec(selectany) COLORREF colors[] = /* from Chris Maunders */
{
	RGB(0x00, 0x00, 0x00), RGB(0xA5, 0x2A, 0x00), RGB(0x00, 0x40, 0x40),
	RGB(0x00, 0x55, 0x00), RGB(0x00, 0x00, 0x5E), RGB(0x00, 0x00, 0x8B),
	RGB(0x4B, 0x00, 0x82), RGB(0x28, 0x28, 0x28),

	RGB(0x8B, 0x00, 0x00), RGB(0xFF, 0x68, 0x20), RGB(0x8B, 0x8B, 0x00),
	RGB(0x00, 0x93, 0x00), RGB(0x38, 0x8E, 0x8E), RGB(0x00, 0x00, 0xFF),
	RGB(0x7B, 0x7B, 0xC0), RGB(0x66, 0x66, 0x66),

	RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0xAD, 0x5B), RGB(0x32, 0xCD, 0x32),
	RGB(0x3C, 0xB3, 0x71), RGB(0x7F, 0xFF, 0xD4), RGB(0x7D, 0x9E, 0xC0),
	RGB(0x80, 0x00, 0x80), RGB(0x7F, 0x7F, 0x7F),

	RGB(0xFF, 0xC0, 0xCB), RGB(0xFF, 0xD7, 0x00), RGB(0xFF, 0xFF, 0x00),
	RGB(0x00, 0xFF, 0x00), RGB(0x40, 0xE0, 0xD0), RGB(0xC0, 0xFF, 0xFF),
	RGB(0x48, 0x00, 0x48), RGB(0xC0, 0xC0, 0xC0),

	RGB(0xFF, 0xE4, 0xE1), RGB(0xD2, 0xB4, 0x8C), RGB(0xFF, 0xFF, 0xE0),
	RGB(0x98, 0xFB, 0x98), RGB(0xAF, 0xEE, 0xEE), RGB(0x68, 0x83, 0x8B),
	RGB(0xE6, 0xE6, 0xFA), RGB(0xFF, 0xFF, 0xFF)
};

void CTPColorMenu::PaintCell(HDC hdc, CELL& cell)
{
	CBrush br = CreateSolidBrush(colors[cell.Index()]);

	CDCHandle dc(hdc);
	CBrushHandle brOld = dc.SelectBrush(br);

	RECT rPaint = cell.Rect(true);
	dc.Rectangle(&rPaint);

	dc.SelectBrush(brOld);
}

////////////////////////////////////////////////////////////
// CTPDateDialog

#ifndef ID_DATEDIALOG
#define ID_DATEDIALOG 1000
#endif

typedef CWinTraitsOR<MCS_NOTODAY> CMyDateCtrlTraits;

#ifdef _WIN32_WCE

typedef CStdControlDialog<ID_DATEDIALOG, CMonthCalendarCtrl, CMyDateCtrlTraits> CTPDateDialog;

#endif


bool CTPDateDialog::ControlDialog::Notify(int, LPNMHDR pnmh)
{
	if (pnmh->code == MCN_SELECT)
	{
		PostMessage(WM_COMMAND, IDOK);
	}

	return false;
};

bool CTPDateDialog::ControlDialog::Command(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/)
{
	if ((wID == IDOK) && m_Data)
	{
		m_Ctrl.GetCurSel((LPSYSTEMTIME)m_Data);
	}

	return false;
};

////////////////////////////////////////////////////////////
// CTPStatusPaneEditor
//

#define STATUS_LENGTH 127 // Max length of pane text

#ifdef _WIN32_WCE

// CTPEditPaneCtrl, a CEdit with vertical keys sending IDCANCEL to parent +
//		PPC: 'usual' VK_RETURN handling for WM5
//		SmartPhone: handling VK_TBACK as VK_BACK
//

class CTPEditPaneCtrl :
			public CWindowImpl<CTPEditPaneCtrl, CEdit>
{
public:
	DECLARE_WND_SUPERCLASS(L"EditCtrl", CEdit::GetWndClassName())

	BEGIN_MSG_MAP(CTPEditPaneCtrl)
	MESSAGE_RANGE_HANDLER(WM_KEYFIRST, WM_KEYLAST, OnKey)
	END_MSG_MAP()

	LRESULT OnKey(UINT uMsg, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
	{
		if (uMsg == WM_KEYUP)
			switch (wParam)
			{
			case VK_TUP:
			case VK_TDOWN:
				::PostMessage(GetParent(), WM_COMMAND, IDCANCEL, 0);
				break;
#if defined  WIN32_PLATFORM_PSPC
			case VK_RETURN:
				::PostMessage(GetParent(), WM_COMMAND, IDOK, 0);
				break;
#elif defined WIN32_PLATFORM_WFSP
			case VK_TBACK:
				SendMessage(WM_CHAR, VK_BACK);
#endif
			}
		bHandled = FALSE;
		return 1;
	}
};

typedef CInPlaceEditor<STATUS_LENGTH, CTPEditPaneCtrl> CTPPaneEditor;

#ifdef WIN32_PLATFORM_PSPC
bool CTPPaneEditor::Init(LPARAM lParam)
{
	SHSipPreference(m_hWnd, SIP_UP);
	return CInPlaceEditor::DefInit(lParam);
}
#endif // WIN32_PLATFORM_PSPC

#else

typedef CInPlaceEditor<STATUS_LENGTH> CTPPaneEditor;

#endif

class CTPStatusPaneEditor
{
public:
	CTPStatusPaneEditor(HWND hWndStatusBar) : m_sb(hWndStatusBar)
	{}

	CStatusBarCtrl m_sb;

	bool EditPane(int iPane)
	{
		ATLASSERT(m_sb.IsWindow());

		CRect rPane;
		ATLVERIFY(m_sb.GetRect(iPane, rPane));
		rPane.InflateRect(-1, -1);
		rPane.OffsetRect(0, -1);
		m_sb.MapWindowPoints(m_sb.GetParent(), rPane);

		CTempBuffer<TCHAR> sPane(STATUS_LENGTH);
		m_sb.GetText(iPane, sPane);

		bool bRes = CTPPaneEditor::Edit(rPane, sPane, m_sb.GetParent());

		if (bRes)
		{
			m_sb.SetText(iPane, sPane);
		}

		return bRes;
	}
};


#ifdef _WIN32_WCE

// Runtime device information
class Device
{
	static bool _b2003, _bSP;
public:
	Device()
	{
		OSVERSIONINFO osvi;
		GetVersionEx(&osvi);
		_b2003 = osvi.dwMajorVersion < 5;
		WCHAR sType[32];
		SystemParametersInfo(SPI_GETPLATFORMTYPE, 32, sType, FALSE);
		_bSP = _wcsnicmp(sType, L"SmartPhone", 10) == 0;
	}
	static const bool Is2003()
	{
		return _b2003;
	}
	static const bool IsSmartPhone()
	{
		return _bSP;
	}
} _device;

bool Device::_b2003, Device::_bSP;

////////////////////////////////////////////////////////////
// CTPFileDialog

#if _WIN32_WCE < 0x500 && defined(WIN32_PLATFORM_WFSP)
// No WS_TABSTOP for SmartPhone 2003 controls
typedef CFileTreeTraits CFileDialogTreeTraits;
typedef CFileListTraits CFileDialogListTraits;
#else
typedef CWinTraitsOR<WS_TABSTOP, 0, CFileTreeTraits> CFileDialogTreeTraits;
typedef CWinTraitsOR<WS_TABSTOP, 0, CFileListTraits> CFileDialogListTraits;
#endif

typedef CStdHSplitDialog < ID_FILEDIALOG, CDirTreeCtrl, CFileListCtrl,
CFileDialogTreeTraits, CFileDialogListTraits > CTPFileDialog;

#ifdef WIN32_PLATFORM_PSPC
bool CTPFileDialog::EmptyDialog::Init(LPARAM lParam)
{
	return DefInit(lParam);
}
#endif

bool CTPFileDialog::SplitDialog::Init(LPARAM lParam)
{
	ATLASSERT(!lParam || !IsBadWritePtr((LPVOID)lParam, MAX_PATH * sizeof(TCHAR)));

	SplitDialog::DefInit(lParam);
	m_Right.SetExtendedListViewStyle(CFileDialogListTraits::GetWndExStyle(0));
	m_Right.Init(Device::IsSmartPhone() ? LVS_SMALLICON : LVS_REPORT);
	CString* pInitRoot = (CString*)lParam;
	m_Left.Init(*pInitRoot);
	SetActivePane(SPLIT_PANE_LEFT);

	return false;
}

bool CTPFileDialog::SplitDialog::Notify(int /*idCtrl*/, LPNMHDR pnmhdr)
{
	switch (pnmhdr->code)
	{
	case NM_SETFOCUS:
		{
			SetDefaultActivePane(pnmhdr->hwndFrom);

			TCHAR	chFile[MAX_PATH * sizeof(TCHAR)];
			ZeroMemory(chFile, MAX_PATH);
			::LoadString(_Module.m_hInst, IDS_FILE, chFile, MAX_PATH);
			TCHAR	chFolder[MAX_PATH];
			ZeroMemory(chFolder, MAX_PATH * sizeof(TCHAR));
			::LoadString(_Module.m_hInst, IDS_FOLDER, chFolder, MAX_PATH);

			LPTSTR lpText = GetDefaultActivePane() == SPLIT_PANE_RIGHT ? chFolder : chFile;
			SetMenuBarCommand((UINT)ID_NEXT_PANE, (UINT)ID_NEXT_PANE, lpText);
		}
		break;
	case FTCN_SELECT:
		m_Right.SetFiles(m_Left.GetFileTreePath());
		break;
	default:
		return false;
	}

	return true;
}

bool CTPFileDialog::SplitDialog::Command(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/)
{
	if (wID == IDOK)
	{
		if (m_Data)
		{
			const int iCount = m_Right.GetItemCount();

			if ( 0 < iCount )
			{
				CString* psFileList = (CString*)(m_Data);
				psFileList->Empty();
				CString strPath(m_Right.GetFilePath()), strFile;

				for ( int i = 0; i < iCount; ++i )
				{
					if ( m_Right.GetCheckState(i) )
					{
						m_Right.GetItemText(i, 0, strFile.GetBuffer(MAX_PATH), MAX_PATH);

						strFile.ReleaseBuffer();

						strFile = strPath + _T("\\") + strFile;

						*psFileList += (strFile + _T("|"));
					}
				}
			}
		}

		return false;
	}

	return SplitDialog::PaneCommand(wID);
};

#endif // _WIN32_WCE
